#include "../../../include/online/WebPage.hpp"
#include "../../../include/cppjieba/Jieba.hpp"
#include <codecvt>

// const char* const DICT_PATH = "../../../include/cppjieba/dict/jieba.dict.utf8";
// const char* const HMM_PATH = "../../../include/cppjieba/dict/hmm_model.utf8";
// const char* const USER_DICT_PATH = "../../../include/cppjieba/dict/user.dict.utf8";
// const char* const IDF_PATH = "../../../include/cppjieba/dict/idf.utf8";
// const char* const STOP_WORD_PATH = "../../../include/cppjieba/dict/stop_words_zh.txt";

// Constructor
// WebPage::WebPage(std::string& doc)
WebPage::WebPage(std::string& doc, cppjieba::Jieba& jieba)
{
    processDoc(doc);
    processWordsMap(jieba);
    calcTopK();
}

// 获取文档的docId
int WebPage::getDocId()
{
    return _docId;
}

// 获取文档的标题
std::string WebPage::getTitle()
{
    return _docTitle;
}

std::string WebPage::getUrl()
{
    return _docUrl;
}

// 
std::string WebPage::summary(const std::vector<std::string>& queryWords)
{
    return _docSummary;
}

// 获取文档的词频统计map
// void WebPage::processWordsMap()
void WebPage::processWordsMap(cppjieba::Jieba & jieba)
{   
    using std::cout;
    using std::endl;
    
    std::vector<std::string> wordsVec;     // 保存文档的分词结果
    // generate words vector
    jieba.Cut((_docTitle + _docContent), wordsVec, true);

    std::set<std::string> stopWordList;
    std::ifstream ifs("/home/suika/SearchEngine/include/cppjieba/dict/stop_words.utf8");
    std::string stopWord;
    while(getline(ifs, stopWord)){
        stopWordList.insert(stopWord);
    }
    for(auto word : wordsVec){
        if(word != " " && find(stopWordList.begin(), stopWordList.end(), word) == stopWordList.end()){
            ++_wordsMap[word];
        }
    }

    #if 0
    cout << "test words map: " << endl;
    for(const auto& iter : _wordsMap){
        cout << iter.first << " " << iter.second << endl;
    }
    #endif
}

std::map<std::string, int>& WebPage::getWordsMap(){
    return _wordsMap;
}

// 对格式化文档进行处理
// void WebPage::processDoc(const std::string& doc, Configuration& config, WordSegmentation&)
void WebPage::processDoc(const std::string& doc)
{
    using std::cout;
    using std::endl;

    size_t beg = 0, end = 0;
    beg = doc.find("<docid>");
    end = doc.find("</docid>");
    _docId = std::stoi(doc.substr(beg + 7, end - beg -7));
    // cout << "_docId: " << _docId << endl;

    beg = doc.find("<title>");
    end = doc.find("</title>");
    _docTitle = doc.substr(beg + 7, end - beg -7);
    // cout << "_docTitle:" << _docTitle << endl;

    beg = doc.find("<url>");
    end = doc.find("</url>");
    _docUrl = doc.substr(beg + 5, end - beg -5);
    // cout << "_docUrl: " << _docUrl << endl;
    
    beg = doc.find("<content>");
    end = doc.find("</content>");
    _docContent = doc.substr(beg + 9, end - beg - 9);
    // cout << "_docContent: " << _docContent << endl;

    size_t summaryLen = ((100 > _docContent.size()) ? _docContent.size() : 100);
    // 使用宽字符串确保截取文章作为summary不出现乱码
    std::wstring_convert<std::codecvt_utf8<wchar_t>> converter;
    std::wstring wstr = converter.from_bytes(_docContent);
    std::wstring wSummary = wstr.substr(0, summaryLen);
    _docSummary = converter.to_bytes(wSummary) + "...";
    // cout << "_docSummary: " << _docSummary << endl;

}

bool cmp(std::map<std::string, int> lhs, std::map<std::string, int> rhs){
    
}

// 求取文档的topk词集
void WebPage::calcTopK(int k)
{
    using std::cout;
    using std::endl;

    // sort
    std::vector<std::pair<std::string, int>> vec(_wordsMap.begin(), _wordsMap.end());
    sort(vec.begin(), vec.end(), [](const std::pair<std::string, int>& lhs, const std::pair<std::string, int>& rhs) {
        return lhs.second > rhs.second;
    });
    for(size_t i = 0; i < k && i < vec.size(); ++i){
        _topWords.push_back(vec[i].first);
    }

    #if 0
    // test
    cout << endl;
    cout << "topWords: " << endl;
    for(const auto& iter : _topWords){
        cout << iter << endl;
    }
    #endif

}

// 判断两篇文档是否相等
bool operator==(const WebPage& lhs, const WebPage& rhs)
{

}

// 对文档按docID进行排序
bool operator< (const WebPage& lhs, const WebPage& rhs)
{

}